﻿#include "../../../includes/widgets/libcwebuimanager.h"
#include "../../../includes/QsLog/QsLog.h"

#include <QLayout>

CWebUIManager::CWebUIManager(QCoreApplication* app,int argc, char* argv[],QObject *parent)
{
#ifdef ENABLE_QCEFVIEW
    m_cefViewWidget = NULL;
    init_QCefView(app,argc,argv);
#else
#ifdef ENABLE_WEBENGINE
    m_webChannel.registerObject("CWebUIManager",this);
#endif
#endif
}

CWebUIManager::~CWebUIManager()
{
#ifdef ENABLE_QCEFVIEW
    if(m_cefContext) m_cefContext->deleteLater();
    if(m_cefViewWidget) m_cefViewWidget->deleteLater();
#endif
}

/**
 * @brief CWebUIManager::OpenUrl 打开一个url
 *
 * @param pLayout 用于显示我们打开的网页控件
 * @param url 要打开的url
 * @param isShow 是否要显示，初始是一打开就显示
 * @param isContentMenu 是否要使用右键菜单
 */
void CWebUIManager::openUrl(QLayout *pLayout,QString url,
                            bool isShow,bool isContentMenu,
                            QWidget *parent)
{
    if(pLayout == NULL || url.isEmpty())
        return;

    QLOG_INFO()<<"CWebUIManager::openUrl:"<<url;

#ifdef ENABLE_QCEFVIEW
    QCefSetting setting;
    // here we just set the default background to blue
    //setting.setBackgroundColor(QColor::fromRgb(0, 0, 0));

    m_cefViewWidget = new QCefView(url,&setting,parent);
    pLayout->addWidget(m_cefViewWidget);

    connect(m_cefViewWidget,
            SIGNAL(invokeMethod(int, qint64, const QString&, const QVariantList&)),
            this,
            SLOT(onInvokeMethod(int, qint64, const QString&, const QVariantList&)));

    connect(m_cefViewWidget,
            SIGNAL(loadError(int,qint64,bool,int,const QString&,const QString&)),
            this,
            SLOT(onloadError(int,qint64,bool,int,const QString&,const QString&)));

    if(!isContentMenu) m_cefViewWidget->setContextMenuPolicy(Qt::NoContextMenu);
    if(!isShow) m_cefViewWidget->hide();
#else
#ifdef ENABLE_WEBENGINE
    pLayout->addWidget(&m_webView);
    m_webView.load(QUrl(url));
    m_webView.page()->setWebChannel(&m_webChannel);

    if(!isContentMenu) m_webView.setContextMenuPolicy(Qt::NoContextMenu);
    if(isShow) m_webView.show();
#endif
#endif
}

/**
 * @brief CWebUIManager::setShow 是否显示网页
 * @param isShow 是否要显示网页控件
 */
void CWebUIManager::setShow(bool isShow)
{
#ifdef ENABLE_QCEFVIEW
    if(m_cefViewWidget)
    {
        if(isShow) m_cefViewWidget->show();
        else m_cefViewWidget->hide();
    }
#else
#ifdef ENABLE_WEBENGINE
    if(isShow) m_webView.show();
    else m_webView.hide();
#endif
#endif
}

/**
 * @brief init_QCefView 初始化QCefView
 * @param argc
 * @param argv
 */
void CWebUIManager::init_QCefView(QCoreApplication* app,int argc, char* argv[])
{
#ifdef ENABLE_QCEFVIEW
    // build QCefConfig
      QCefConfig config;
      // set user agent
      config.setUserAgent("CWebUIManager");
      // set log level
      config.setLogLevel(QCefConfig::LOGSEVERITY_DEFAULT);
      // set JSBridge object name (default value is QCefViewClient)
      config.setBridgeObjectName("WebUIManager");
      // port for remote debugging (default is 0 and means to disable remote debugging)
      config.setRemoteDebuggingPort(9000);
      // set background color for all browsers
      // (QCefSetting.setBackgroundColor will overwrite this value for specified browser instance)
      config.setBackgroundColor(Qt::lightGray);

      // WindowlessRenderingEnabled is set to true by default,
      // set to false to disable the OSR mode
      config.setWindowlessRenderingEnabled(true);

      // add command line args, you can any cef supported switches or parameters
      config.addCommandLineSwitch("use-mock-keychain");
      // config.addCommandLineSwitch("disable-gpu");
      // config.addCommandLineSwitch("enable-media-stream");
      // config.addCommandLineSwitch("allow-file-access-from-files");
      // config.addCommandLineSwitch("disable-spell-checking");
      // config.addCommandLineSwitch("disable-site-isolation-trials");
      // config.addCommandLineSwitch("enable-aggressive-domstorage-flushing");
      config.addCommandLineSwitchWithValue("renderer-process-limit", "1");
      // config.addCommandLineSwitchWithValue("disable-features", "BlinkGenPropertyTrees,TranslateUI,site-per-process");

      // create QCefContext instance with config,
      // the lifecycle of cefContext must be the same as QApplication instance
      m_cefContext = new QCefContext(app, argc, argv, &config);
#endif
}

/**
 * @brief reLoadData 重新载入网页
 */
void CWebUIManager::reLoadData(void)
{
#ifdef ENABLE_QCEFVIEW
    if(m_cefViewWidget) m_cefViewWidget->browserReload();
#else
#ifdef ENABLE_WEBENGINE
    m_webView.reload();
#endif
#endif
}

/**
 * @brief CWebUIManager::sendDataToQt 处理从网页中发送过来的数据
 *
 * @param data 网页发送过来的数据
 */
void CWebUIManager::sendDataToQt(const QString data)
{
    if(data.isEmpty())
        return;

    QLOG_INFO()<<"CWebUIManager::sendDataToQt:"<<data;

#ifdef ENABLE_QCEFVIEW

#else
    emit UrlSendedData(data);
#endif
}

void CWebUIManager::onloadError(int browserId,
               qint64 frameId,
               bool isMainFrame,
               int errorCode,
               const QString& errorMsg,
               const QString& failedUrl)
{
    QLOG_ERROR()<<QString::asprintf("CWebUIManager::onloadError errorCode:%d",errorCode)
                <<errorMsg
                <<failedUrl;
}

void CWebUIManager::onInvokeMethod(int browserId, qint64 frameId, const QString& method, const QVariantList& arguments)
{
    if (0 != method.compare("SendData") ||
        arguments.size() != 1 ||
        arguments[0].type() != QVariant::String)
        return;

#ifdef ENABLE_QCEFVIEW
    emit UrlSendedData(arguments[0].toString());
#endif
}

/**
 * @brief CWebUIManager::sendDataToUrl 发送数据给网页
 * @param data 要给网页的数据
 */
void CWebUIManager::sendDataToUrl(const QString data)
{
    if(data.isEmpty())
        return;

    QLOG_INFO()<<"CWebUIManager::sendDataToUrl:"<<data;

#ifdef ENABLE_QCEFVIEW
    if(m_cefViewWidget)
    {
        QMetaObject::invokeMethod(
          this,
          [=]() {
            QCefEvent event("ReceiveData");
            event.arguments().append(QVariant::fromValue(data));

            m_cefViewWidget->broadcastEvent(event);
          },
          Qt::QueuedConnection);
    }
#else
    emit onProcessQtSendedData(data);
#endif
}
